package com.ziq.zcamp.community

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.graphics.Color
import android.location.LocationManager
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.Toast
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.ScreenUtils
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.request.ImageRequest
import com.ziq.base.base.BaseFragment
import com.ziq.base.extension.*
import com.ziq.base.utils.permission.PermissionUtil
import com.ziq.base.view.recycleview.BaseListAdapter
import com.ziq.zcamp.R
import com.ziq.zcamp.bean.post.PostingNearbyDetail
import com.ziq.zcamp.databinding.FragmentCommunityNearbyBinding
import com.ziq.zcamp.databinding.ItemCommunityRecommendedBinding
import com.ziq.zcamp.login.ActionAfterLogin
import com.ziq.zcamp.login.LoginActivity
import com.ziq.zcamp.manager.*
import com.ziq.zcamp.mine.PersonalHomePageActivity
import com.ziq.zcamp.util.ImageUtil
import com.ziq.zcamp.util.PictureUtil
import com.ziq.zcamp.view.StatusView
import com.ziq.zcamp.view.layoutmanager.CustomStaggeredGridLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import java.text.DecimalFormat
import kotlin.math.abs

@AndroidEntryPoint
class CommunityNearbyFragment : BaseFragment(R.layout.fragment_community_nearby){

    companion object {
        const val STATUS_VIEW_NO_PERMISSIONS = 99
    }

    val mViewModel: CommunityNearbyViewModel by viewModels()
    private val binding : FragmentCommunityNearbyBinding? by binding()

    private var isFirst = true
    private var onShow = false

    //当前界面的状态
    private var fragmentStatus:Int ?= null
    //第一次展示的时候上报埋点需要等待数据请求完成，使用这个变量进行延迟
    private var buriedPointFirst = true
    //第一次tab切换到附近，如果用户之前是一直拒绝，切换tab直接调起对用户不友好，所以当用户是点击的时候才调起设置界面
    private var firstRequestPermission = true

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding?.root
        binding?.let {
            initView(it)
        }
        initObserver()
    }

    override fun onResume() {
        super.onResume()
        if (isFirst){
            isFirst = false
            initData()
        }
        if (fragmentStatus != null && fragmentStatus != StatusView.LOADING){
            DataManager.changeCommunityPostingBtnShow(fragmentStatus == StatusView.IDLE)
        }
        onShow = true
    }

    var adapter : Adapter? = null
    /**
     * 初始化控件
     */
    private fun initView(binding: FragmentCommunityNearbyBinding) {
        val itemWidth = (ScreenUtils.getScreenWidth() - GlobalContextManager.getResources().getDimensionPixelSize(R.dimen.dimens_dip_24)) / 2
        binding.rvCommunityNearby.layoutManager = CustomStaggeredGridLayoutManager(2,
            StaggeredGridLayoutManager.VERTICAL)
        adapter = Adapter(requireContext(), itemWidth)
        binding.rvCommunityNearby.adapter = adapter
        binding.rvCommunityNearby.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                if (Fresco.hasBeenInitialized() && newState == RecyclerView.SCROLL_STATE_IDLE) {
                    Fresco.getImagePipeline().resume()//恢复加载图片
                }
            }

            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                if(abs(dy) > 25){
                    if(Fresco.hasBeenInitialized() && !Fresco.getImagePipeline().isPaused){
                        Fresco.getImagePipeline().pause()// 暂停图片请求
                    }
                } else if(abs(dy) < 5){
                    if(Fresco.hasBeenInitialized() && Fresco.getImagePipeline().isPaused){
                        Fresco.getImagePipeline().resume()//恢复加载图片
                    }
                }
            }
        })

        binding.rlCommunityNearby.setOnLoadMoreListener {
            mViewModel.dataLoadMore()
        }
        binding.rlCommunityNearby.setOnRefreshListener {
            mViewModel.dataRefresh()
            PostManager.requestSubject()
            CampLifeManager.requestMyCampData()
        }

        mViewModel.nearbyPostingList.observe(viewLifecycleOwner) {
            adapter?.submitList(it)
        }
    }


    /**
     * 初始化观察者
     */
    @SuppressLint("NotifyDataSetChanged")
    private fun initObserver() {
        mViewModel.hasMoreDate.observe(viewLifecycleOwner){
            binding?.rlCommunityNearby?.setNoMoreData(!it)
        }
        mViewModel.statusView.observe(viewLifecycleOwner){
            fragmentStatus = it
            when (it) {
                StatusView.IDLE -> {
                    binding?.rvCommunityNearby?.visibility = View.VISIBLE
                    binding?.statusView?.setStatus(StatusView.IDLE)
                    binding?.rlCommunityNearby?.finishRefresh()
                    binding?.rlCommunityNearby?.finishLoadMore()
                    binding?.rlCommunityNearby?.setEnableLoadMore(true)
                }
                StatusView.LOADING -> {
                    binding?.statusView?.setStatus(StatusView.LOADING)
                }
                StatusView.NO_DATA -> {
                    binding?.rvCommunityNearby?.visibility = View.GONE
                    binding?.rlCommunityNearby?.finishRefresh()
                    binding?.rlCommunityNearby?.finishLoadMore()
                    binding?.statusView?.setStatus(StatusView.NO_DATA)
                    binding?.statusView?.setStatus(
                        StatusView.NO_DATA,
                        isCenter = false,
                        marginTop = 60.dp,
                        imgSrc = R.drawable.pic_no_content_camp,
                        imgWidth = 235.dp,
                        imgHeight = 151.dp,
                        msg = "附近暂无内容～",
                        updateActionBtn = { btn ->
                            btn.setBackgroundResource(R.drawable.selector_book_btn)
                            btn.text = "抢首发"
                            btn.textSize = 14F
                            btn.setTextColor(Color.parseColor("#FFFFFF"))
                            btn.click {
                                postAPost()
                            }
                        }
                    )
                    binding?.rlCommunityNearby?.setEnableLoadMore(false)
                }
                StatusView.NET_ERROR -> {
                    binding?.rvCommunityNearby?.visibility = View.GONE
                    binding?.statusView?.setStatus(
                        StatusView.NET_ERROR,
                        isCenter = false,
                        marginTop = 60.dp,
                        updateActionBtn = { btn ->
                            btn.click {
                                mViewModel.dataRefresh()
                            }
                        })
                    binding?.rlCommunityNearby?.finishRefresh()
                    binding?.rlCommunityNearby?.finishLoadMore()
                    binding?.rlCommunityNearby?.setEnableLoadMore(false)
                }
                STATUS_VIEW_NO_PERMISSIONS ->{
                    binding?.rvCommunityNearby?.visibility = View.GONE
                    binding?.rlCommunityNearby?.finishRefresh()
                    binding?.rlCommunityNearby?.finishLoadMore()
                    binding?.statusView?.setStatus(StatusView.NO_DATA)
                    binding?.statusView?.setStatus(
                        StatusView.NO_DATA,
                        isCenter = false,
                        marginTop = 60.dp,
                        imgSrc = R.drawable.pic_no_content_camp,
                        imgWidth = 235.dp,
                        imgHeight = 151.dp,
                        msg = "授权定位即可浏览附近的人～",
                        updateActionBtn = { btn ->
                            btn.setBackgroundResource(R.drawable.selector_book_btn)
                            btn.text = "授权定位"
                            btn.textSize = 14F
                            btn.setTextColor(Color.parseColor("#FFFFFF"))
                            btn.click {
                                initData()
                            }
                        }
                    )
                    binding?.rlCommunityNearby?.setEnableLoadMore(false)
                }
            }
            if (onShow && fragmentStatus != StatusView.LOADING)
                DataManager.changeCommunityPostingBtnShow(fragmentStatus == StatusView.IDLE)
        }

        DataManager.postingVersion.observe(viewLifecycleOwner) {
            mViewModel.dataRefresh()
        }
        UserManager.instance.postingLike.observe(viewLifecycleOwner) {
            binding?.rvCommunityNearby?.adapter?.notifyDataSetChanged()
        }
    }

    /**
     * 初始化数据
     */
    private fun initData() {
        PermissionUtil.requestLocationPermission(this@CommunityNearbyFragment.requireActivity(), onGrant = {
            try {
                val lm = activity?.getSystemService(Activity.LOCATION_SERVICE) as LocationManager
                val enable = lm.isProviderEnabled(LocationManager.GPS_PROVIDER)
                if (enable){
                    mViewModel.dataRefresh()
                }else{
                    viewOfNoPermission()
                    Toast.makeText(context,"定位服务未开启", Toast.LENGTH_SHORT).show()
                }
            }catch (e:Exception){
                viewOfNoPermission()
            }
        }, onReject = {
            viewOfNoPermission()
        }, onRemind = {
            viewOfNoPermission()
            if (!firstRequestPermission){
                AppUtils.launchAppDetailsSettings()
            }
            firstRequestPermission = false
        })
    }

    private fun viewOfNoPermission(){
        mViewModel.statusView.value = STATUS_VIEW_NO_PERMISSIONS
    }

    private fun postAPost(){
        LoginActivity.checkLogin(object : ActionAfterLogin {
            @SuppressLint("CheckResult")
            override fun action() {
                GlobalContextManager.mainHandler.postDelayed({
                    if(activity != null){
                        PostManager.showPostTypeSelector(requireActivity())
                    }
                }, 500)
            }
        })
    }

    override fun onPause() {
        super.onPause()
        onShow = false
    }

    /**
     * 附近的adapter
     */
    class Adapter(val context : Context, val itemWidth : Int)
        : BaseListAdapter<PostingNearbyDetail, ItemCommunityRecommendedBinding>(){
        override fun areContentsTheSame(
            oldItem: PostingNearbyDetail,
            newItem: PostingNearbyDetail
        ): Boolean {
            return oldItem.post?.post_id == newItem.post?.post_id
        }

        override fun areItemsTheSame(
            oldItem: PostingNearbyDetail,
            newItem: PostingNearbyDetail
        ): Boolean {
            return oldItem.post?.post_id == newItem.post?.post_id
        }

        override fun onCreateViewHolder(
            parent: ViewGroup,
            viewType: Int
        ): BindingViewHolder<ItemCommunityRecommendedBinding> {
            return createBindingViewHolder(parent)
        }

        @SuppressLint("SetTextI18n")
        override fun onBindViewHolder(
            holder: BindingViewHolder<ItemCommunityRecommendedBinding>,
            position: Int
        ) {
            val item = getItem(position)
            val binding = ItemCommunityRecommendedBinding.bind(holder.itemView)
            if(item.post?.p_type == 2){
                binding.ivPostTypeLabel.visibility = View.VISIBLE
                binding.ivPostTypeLabel.setImageResource(R.drawable.icon_post_video_label)
            } else {
                binding.ivPostTypeLabel.visibility = View.GONE
            }

            holder.itemView.click {
                PostManager.navigateToDetailActivity(context, item)
            }

            binding.llUserInfo.click {
                PersonalHomePageActivity.open(context, item.user?.uid?:0)
            }

            if(position == 0 || position == 1){
                val marginTop: Int = GlobalContextManager.getResources().getDimensionPixelSize(R.dimen.dimens_dip_8)
                val lp = binding.cardview.layoutParams as FrameLayout.LayoutParams
                lp.topMargin = marginTop
                binding.cardview.layoutParams = lp
            } else {
                val lp = binding.cardview.layoutParams as FrameLayout.LayoutParams
                lp.topMargin = 0
                binding.cardview.layoutParams = lp
            }

            var content = ""
            if(item.post?.title?.isNotEmpty() == true){
                content = "${item.post?.title}"
            }else if(item.post?.content?.isNotEmpty() == true){
                content = "${item.post?.content}"
            }
            if (content.isEmpty()){
                binding.title.visibility = View.GONE
                val paddingtop = GlobalContextManager.getResources().getDimensionPixelSize(R.dimen.dimens_dip_12)
                val lp = binding.avator.layoutParams as LinearLayout.LayoutParams
                lp.topMargin = paddingtop
                lp.bottomMargin = paddingtop
                binding.avator.layoutParams = lp
            } else {
                binding.title.visibility = View.VISIBLE
                val paddingtop = GlobalContextManager.getResources().getDimensionPixelSize(R.dimen.dimens_dip_8)
                val lp = binding.avator.layoutParams as LinearLayout.LayoutParams
                lp.topMargin = paddingtop
                lp.bottomMargin = paddingtop
                binding.avator.layoutParams = lp
            }

            binding.title.text = content
            binding.name.text = "${item.user?.nick_name}"
            ImageUtil.updateImageFromNetwork(binding.avator, item.user?.header_url, ImageRequest.CacheChoice.DEFAULT)

            val imageInfo = item.post?.images?.get(0)
            if(imageInfo != null){
                val params = binding.image.layoutParams as ViewGroup.LayoutParams
                params.width = itemWidth
                params.height = PictureUtil.calculatePictureViewHeight(itemWidth, imageInfo.width, imageInfo.height)
                binding.image.layoutParams = params

                ImageUtil.updateImageFromNetwork(binding.image, imageInfo.url, ImageRequest.CacheChoice.DEFAULT)

            } else {
                val params = binding.image.layoutParams as ViewGroup.LayoutParams
                params.width = itemWidth
                params.height = itemWidth
                binding.image.layoutParams = params
            }

            binding.llDistance.visibility = View.VISIBLE
            if (item.distance in 0..1000){
                binding.distance.text = "1km"
            }else{
                binding.distance.text = "${DecimalFormat("0.0").format((item.distance?:0) / 1000f)}km"
            }


            updateLikeUI(true, item, binding)

            binding.llCommentActionPraise.click {
                LoginActivity.checkLogin(object : ActionAfterLogin {
                    override fun action() {
                        //点赞 帖子
                        if(binding.llCommentActionPraise.isSelected){
                            updateItemDataForUnLike(item, binding)
                            UserManager.instance.unlikePosting(item.post?.post_id?:"", item.user?.uid?:0, item.post?.like_nums?:0,
                                onFail = {
                                    updateItemDataForLike(item, binding)
                                }
                            )
                        } else {
                            updateItemDataForLike(item, binding)
                            UserManager.instance.likePosting(item.post?.post_id?:"", item.user?.uid?:0, item.post?.like_nums?:0,
                                onFail = {
                                    updateItemDataForUnLike(item, binding)
                                }
                            )
                        }
                    }
                })
            }
        }



        fun updateItemDataForLike(item: PostingNearbyDetail, binding: ItemCommunityRecommendedBinding){
            item.post?.let {
                val likeNum = it.like_nums?:0
                it.like_nums = likeNum + 1
                it.is_like = true
            }
            updateLikeUI(false,item, binding)
        }

        fun updateItemDataForUnLike(item: PostingNearbyDetail, binding: ItemCommunityRecommendedBinding){
            item.post?.let {
                val likeNum = it.like_nums?:0
                if(likeNum > 0 ){
                    it.like_nums = likeNum - 1
                }
                it.is_like = false
            }
            updateLikeUI(false, item, binding)
        }

        @SuppressLint("SetTextI18n")
        fun updateLikeUI(considerManager: Boolean, item: PostingNearbyDetail, binding: ItemCommunityRecommendedBinding){
            var likeNum = item.post?.like_nums?:0
            if(considerManager && item.post?.post_id?.isNotEmpty() == true && UserManager.instance.postingLike.value?.contains(item.post?.post_id) == true){
                binding.llCommentActionPraise.isSelected = UserManager.instance.postingLike.value!![item.post!!.post_id]!!.isLike
                likeNum = UserManager.instance.postingLike.value!![item.post!!.post_id]!!.num
                item.post?.like_nums = likeNum
            } else {
                binding.llCommentActionPraise.isSelected = item.post?.is_like?:false
            }
            binding.tvCommentActionPraiseCount.visibility = View.VISIBLE
            when {
                likeNum > 10000 -> {
                    binding.tvCommentActionPraiseCount.text = String.format("%.1f", (likeNum / 10000.0)) + GlobalContextManager.getString(
                        R.string.wan)
                }
                likeNum == 0 -> {
                    binding.tvCommentActionPraiseCount.text = ""
                    binding.tvCommentActionPraiseCount.visibility = View.GONE
                }
                else -> {
                    binding.tvCommentActionPraiseCount.text = likeNum.toString()
                }
            }
        }
    }

}